<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>07完整的柱形图</title>
    <script src="./node_modules/d3/dist/d3.min.js"></script>
    <style>
        .axis path,
        .axis line {
            fill: none;
            stroke: black;
            shape-rendering: crispEdges;
        }

        .axis text {
            font-family: sans-serif;
            font-size: 11px;
        }
    </style>
</head>
<body>

</body>
</html>
<script>
    const width = 400; // 画布的宽度
    const height = 400; // 画布的高度
    const dataset = [10, 20, 30, 40, 33, 24, 12, 5]; // bar的数据
    const padding = {left: 30, right: 30, top: 20, bottom: 20}; // 画布周围留空白的间距
    /*
    * 第一步：添加SVG画布
    * */
    const body = d3.select('body');
    body.append('svg')
        .attr('width', width)
        .attr('height', height)
        .style('border', '1px solid #ccc');
    const svg = body.select('svg');
    /*
    * 第二步：创建比例尺
    * */
    // x轴的比例尺，采用的是序数比例尺
    const xScale = d3.scaleBand()
    // d3.range 设置输入范围从0~dataset.length,相间1(d3.range默认从0开始，间隔为1)
        .domain(d3.range(dataset.length))
        .rangeRound([0, width - padding.left - padding.right]);

    // y轴比例尺，采用的是线性比例尺
    const yScale = d3.scaleLinear()
        .domain([0, d3.max(dataset)])
        // 注意了：屏幕Y轴方向是由上向下，所以为了实现y轴数据从下向上递增，比例尺需要反方向
        // y轴值域范围是svg的高度减去上下空白区域的长度
        .range([height - padding.top - padding.bottom, 0]);

    /*
    * 第三步：定义坐标
    * */
    // X轴坐标
    const xAxis = d3.axisBottom()
        .scale(xScale) // 设置坐标轴比例尺
    // Y轴坐标
    const yAxis = d3.axisLeft()
        .scale(yScale)

    /*
    * 第四步：将坐标放到
    * */
    // 设置x轴
    svg.append('g')
        .attr('class', 'axis')
        .attr('transform', `translate(${padding.left},${height - padding.bottom})`)
        .call(xAxis)
    // 设置Y轴
    svg.append('g')
        .attr('class', 'axis')
        .attr('transform', `translate(${padding.left},${padding.top})`)
        .call(yAxis)
    /*
    * 绘制柱状图并放到svg中
    * */
    //矩形之间的空白
    const rectPadding = 4;
    svg.selectAll('rect')
        .data(dataset)
        .enter()
        .append('rect')
        .attr('transform', `translate(${padding.left},${padding.top})`)
        .attr('y', (data) => {
            return yScale(data)
        })
        .attr('x', (data, i) => {
            return xScale(i) + rectPadding / 2
        })
        .attr('width', (data, i) => {
            return xScale.bandwidth() - rectPadding
        })
        .attr('height', (data, i) => {
            return height - padding.top - padding.bottom - yScale(data)
        })
        .attr('fill', '#409EFF');

    /*
    * 添加文字
    * */
    body.select('svg')
        .selectAll('.text')
        .data(dataset)
        .enter()
        .append('text')
        .attr('class', '.text')
        .attr('transform', `translate(${padding.left},${padding.top})`)
        .attr('x', (data, i) => {
            return xScale(i) + rectPadding / 2
        })
        .attr('y', (data, i) => {
            return yScale(data)
        })
        .attr('dx', (data, i) => {
            return (xScale.bandwidth() - rectPadding) / 2
        })
        .attr("dy", function (d) {
            return 20;
        })
        .text((data) => {
            return data
        })
        .style('fill', '#fff')
        .attr('text-anchor', 'middle') // 将文字居中(文字中心点就是x轴坐标)
</script>
